#pragma once

#include "msgObj.hpp"
#include "nlohmann/json.hpp"
#include <any>
#include <chrono>
#include <cstddef>
#include <string>
#include <vector>

namespace Protocol {
class DevCyclicReportMsgObject {
private:
    std::size_t tick;
    std::size_t time;
    std::string src;

    struct Dev {
        std::size_t id;
        std::string status;
        struct Point {
            std::string key;
            std::any val;
            std::size_t time;

            Point(const std::string &k, const std::any &v, std::size_t t)
                : key(k), val(v), time(t) {}

            friend void to_json(nlohmann::json &j, const Point &p) {
                j = {{"key", p.key}, {"val", any_to_json(p.val)}, {"time", p.time}};
            }
        };
        std::vector<Point> points;

        Dev(std::size_t id, const std::string &s, const std::vector<Point> &p)
            : id(id), status(s), points(p) {}

        friend void to_json(nlohmann::json &j, const Dev &d) {
            j = {{"id", d.id}, {"status", d.status}, {"points", d.points}};
        }
    };

    std::vector<Dev> dev;

public:
    DevCyclicReportMsgObject(std::size_t time, std::size_t id, const std::string &key, const std::any &val)
        : tick(1),
          time(time),
          src("dev_dlt698"),
          dev({Dev{id,
                   "online",
                   {Dev::Point(key, val, time)}}}) {}

    friend void to_json(nlohmann::json &j, const DevCyclicReportMsgObject &d) {
        j = {{"tick", d.tick}, {"src", d.src}, {"time", d.time}, {"dev", d.dev}};
    }
};

};  // namespace Protocol
